package com.magnificent.panda.model.generator.log;

import com.magnificent.panda.model.generator.log.tax.TaxLogElement;
import jxl.Cell;
import jxl.Sheet;
import jxl.Workbook;
import jxl.read.biff.BiffException;
import jxl.write.Label;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;
import jxl.write.WriteException;

import java.io.*;
import java.util.*;

/**
 * User: Babanin
 * Date: 07.10.2010
 * Time: 12:57:41
 */
public class TaxLogParser {

    public static final int QUEARTER = 90;

    private static final String THREE_MONTHS = "В 3";
    private static final String TEMPLATE_EXCEL_DOC = "task2007.xls";

    private static final int START_QUARTER_COLUMN = 4;
    private static final int END_QUARTER_COLUMN = 5;

    private static final int START_PREPARED_QUARTER_COLUMN = 6;
    private static final int START_SECOND_PREPARED_QUARTER_COLUMN = 7;
    private static final int END_PREPARED_QUARTER_COLUMN = 8;
    private static final int END_SECOND_PREPARED_QUARTER_COLUMN = 9;

    private static final int START_DAY_COLUMN = 10;
    private static final int END_DAY_COLUMN = 11;
    private static final int DIFF_DAY_COLUMN = 12;

    public static List<TaxLogElement> parse() throws FileNotFoundException {
        List<TaxLogElement> result = new ArrayList<TaxLogElement>();
        Scanner in = new Scanner(new File("task2007.txt"));

        String data = null;
        while (in.hasNextLine()) {
            data = in.nextLine().replaceAll("  ", " ").replaceAll("\t", " ").trim();

            if (!containLetters(data)) {
                String[] dataStrs = data.split("  ");
                if (dataStrs.length == 2) {
                    String[] dataOneStrs = dataStrs[0].split(" ");
                    String[] dataTwoStrs = dataStrs[1].split(" ");

                    int[] startData = new int[dataOneStrs.length];
                    int[] endData = new int[dataTwoStrs.length];

                    for (int i = 0; i < dataOneStrs.length; i++) {
                        String val = dataOneStrs[i].trim();

                        if (!"".equals(val)) {
                            startData[i] = Integer.parseInt(val);
                        }
                    }

                    for (int i = 0; i < dataTwoStrs.length; i++) {
                        String val = dataTwoStrs[i].trim();

                        if (!"".equals(val)) {
                            endData[i] = Integer.parseInt(val);
                        }
                    }

                    result.add(new TaxLogElement(startData, endData));
                }
            }
        }

        in.close();

        return result;
    }

    private static boolean containLetters(String data) {
        for (int i = 0; i < data.length(); i++) {
            if (Character.isLetter(data.charAt(i))) {
                return true;
            }
        }

        return false;
    }


    public static void main(String[] args) throws BiffException, IOException, WriteException {
        /*
        List<TaxLogElement> quarterElementList = new ArrayList<TaxLogElement>();

        try {
            List<TaxLogElement> logElementList = parse();

            for (TaxLogElement element : logElementList) {
                System.out.println(element);

                System.out.println("\nUPDATED\n");

                TaxLogElement quarterElement = generateQuarterElementFromQuarter(element);
                quarterElementList.add(quarterElement);

                System.out.println(quarterElement);
                System.out.println("\n------------------------\n");
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

        Integer[] flow = generateFlow(quarterElementList);
        System.out.println("\n\nFlow: ");
        for (Integer integer : flow) {
            System.out.print(integer + " ");
        }

        Integer[] diffFlow = generateDiffFlow(flow);
        System.out.println("\n\nDiff flow: ");
        for (Integer integer : diffFlow) {
            System.out.print(integer + " ");
        }

        Integer[] flowByDay = generateDayFlow(flow);
        System.out.println("\n\nFlow by day: ");
        for (Integer integer : flowByDay) {
            System.out.print(integer + " ");
        }

        System.out.println("\n");
        */

        for (int i = 0; i < 10; i++) {
            generateXls(i);
        }
    }

    public static int generateValueFromQuarter(int[] quarter) {
        if (quarter == null) {
            return -1;
        }

        if (quarter.length == 1) {
            double val = 1.0 / QUEARTER;

            return (int) (Math.random() / val + (quarter[0] - 1) * QUEARTER) + 1;
        } else if (quarter.length == 2) {
            Arrays.sort(quarter);

            int diff = quarter[1] - quarter[0] + 1;
            double val = 1.0 / (QUEARTER * diff);

            return (int) (Math.random() / val + (quarter[0] - 1) * QUEARTER) + 1;
        } else {
            throw new IllegalStateException("Quarter elements > 2");
        }
    }

    public static TaxLogElement generateQuarterElementFromQuarter(TaxLogElement element) {
        if (element == null) {
            return null;
        }

        if (element.getStart() == null) {
            return null;
        }

        int start = generateValueFromQuarter(element.getStart());

        int end = start + QUEARTER + new Random().nextInt(QUEARTER);
        if (element.getEnd() != null) {
            end = generateValueFromQuarter(element.getEnd());
        }

        if (start >= end) {
            int temp = start;
            start = end;
            end = temp;
        }

        return new TaxLogElement(
                new int[]{start},
                new int[]{end});
    }


    public static Integer[] generateFlow(List<TaxLogElement> elements) {
        List<Integer> flow = new ArrayList<Integer>();

        for (TaxLogElement element : elements) {
            flow.add(element.getStart()[0]);
        }

        Collections.sort(flow);

        return flow.toArray(new Integer[elements.size()]);
    }

    public static Integer[] generateDiffFlow(Integer[] elements) {
        Integer[] result = new Integer[elements.length - 1];

        for (int i = 0; i < result.length; i++) {
            result[i] = elements[i + 1] - elements[i];
        }

        return result;
    }

    public static Integer[] generateDayFlow(Integer[] elements) {
        Integer[] result = new Integer[QUEARTER * 4];

        for (int i = 0; i < result.length; i++) {
            result[i] = 0;
        }

        for (Integer element : elements) {
            result[element - 1]++;
        }

        return result;
    }

    public static void generateXls(int output) throws BiffException, IOException, WriteException {
        Workbook templateWorkbook = Workbook.getWorkbook(new File(TEMPLATE_EXCEL_DOC));
        WritableWorkbook workbook = Workbook.createWorkbook(new File("output\\" + output + "_task.xls"), templateWorkbook);

        PrintWriter diffWriter = new PrintWriter(new FileWriter("output\\" + output + "_diff.txt"));
        PrintWriter startWriter = new PrintWriter(new FileWriter("output\\" + output + "_start.txt"));

        WritableSheet sheet = workbook.getSheet(1);
        Sheet templateSheet = templateWorkbook.getSheet(1);

        for (int i = 6; i < templateSheet.getRows(); i++) {
            String start = templateSheet.getCell(START_PREPARED_QUARTER_COLUMN, i).getContents();
            String startSecond = templateSheet.getCell(START_SECOND_PREPARED_QUARTER_COLUMN, i).getContents();

            String end = templateSheet.getCell(END_PREPARED_QUARTER_COLUMN, i).getContents();
            String endSecond = templateSheet.getCell(END_SECOND_PREPARED_QUARTER_COLUMN, i).getContents();

            if (!isDirtyData(start, end)) {
                TaxLogElement quarterLogElement = generateQuarterElementFromQuarter(parsePreparedLogElement(start, startSecond, end, endSecond));

                if (quarterLogElement != null) {
                    int diff = quarterLogElement.getEnd()[0] - quarterLogElement.getStart()[0];

                    sheet.addCell(new Label(START_DAY_COLUMN, i, "" + quarterLogElement.getStart()[0]));
                    sheet.addCell(new Label(END_DAY_COLUMN, i, "" + quarterLogElement.getEnd()[0]));
                    sheet.addCell(new Label(DIFF_DAY_COLUMN, i, "" + diff));

                    startWriter.write("" + quarterLogElement.getStart()[0] + "\n");
                    diffWriter.write("" + diff + "\n");
                }
            }
        }

        workbook.write();
        workbook.close();

        diffWriter.close();
        startWriter.close();
    }

    private static boolean isDirtyData(String start, String end) {
        if (end == null || start == null) {
            return true;
        }

        if ("".equals(end) || "".equals(start)) {
            return true;
        }

        boolean startHasDigit = false;
        for (int i = 0; i < start.length(); i++) {
            if (Character.isDigit(start.charAt(i))) {
                startHasDigit = true;
                break;
            }
        }

        boolean endHasDigit = false;
        for (int i = 0; i < end.length(); i++) {
            if (Character.isDigit(end.charAt(i))) {
                endHasDigit = true;
                break;
            }
        }

        return !(startHasDigit && endHasDigit);
    }


    public static TaxLogElement parsePreparedLogElement(String start, String startSecond, String end, String endSecond) {
        int startVal = Integer.parseInt(start);
        int startSecVal = !"".equals(startSecond) ? Integer.parseInt(startSecond) : -1;

        int endVal = !end.contains("еще") ? Integer.parseInt(end) : Integer.MIN_VALUE;
        int endSecVal = !"".equals(endSecond) ? Integer.parseInt(endSecond) : -1;

        int[] startA = null;
        if (startSecVal != -1) {
            startA = new int[2];
            startA[1] = startSecVal;
        } else {
            startA = new int[1];
        }
        startA[0] = startVal;

        int[] endA = null;
        if (endVal != Integer.MIN_VALUE) {
            if (endSecVal != -1) {
                endA = new int[2];
                endA[1] = endSecVal;
            } else {
                endA = new int[1];
            }

            endA[0] = endVal;
        }

        return new TaxLogElement(startA, endA);
    }

    public static TaxLogElement parseLogElement(String start, String end) {
        if (start == null || end == null) {
            return null;
        }

        int[] startArray = null;
        if (!start.contains(THREE_MONTHS)) {
            String[] startQuarters = start.replaceAll("кв", "").replace('.', ' ').trim().split("-");

            startArray = new int[startQuarters.length];
            for (int i = 0; i < startQuarters.length; i++) {
                if (startQuarters[i].equals("")) {
                    continue;
                }

                startArray[i] = Integer.parseInt(startQuarters[i]);
            }
        }

        int[] endArray = null;
        if (!end.contains(THREE_MONTHS)) {
            String[] endQuarters = end.replaceAll("кв.", "").replace('.', ' ').trim().split("-");

            endArray = new int[endQuarters.length];
            for (int i = 0; i < endQuarters.length; i++) {
                if (endQuarters[i].equals("")) {
                    continue;
                }

                endArray[i] = Integer.parseInt(endQuarters[i]);
            }
        }

        return new TaxLogElement(startArray, endArray);
    }
}

  /* converted to utf8 */